package net.nicetuan.growth.aop;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.google.common.collect.Maps;
import com.yhdx.common.lang.CommonResultCode;
import com.yhdx.common.lang.Response;
import com.yhdx.common.util.ResponseUtils;
import com.yhdx.common.util.StringUtils;
import com.yhdx.tool.ctx.CurrentContextHolder;
import com.yhdx.tool.log.domain.CommonLogger;
import com.yhdx.tool.log.util.LoggerUtils;
import com.yhdx.tool.lookout.NicetuanLookoutRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Map;

/**
 * @author YangJian
 * @description 拦截异常并统一处理
 * @date 2018/12/7 17:34
 * @modified
 */
@ControllerAdvice
public class AgbweappControllerAdvice implements RequestBodyAdvice {

    private final static String CURRENT_CONTEXT_KEY = "request_body_advice_method_name";

    @Autowired
    private NicetuanLookoutRegistry nicetuanLookoutRegistry;

    /**
     * 请求参数json解析全局异常捕捉处理
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = {JsonMappingException.class, JsonParseException.class})
    public Response errorHandler(Exception e) {

        String methodName = (String) CurrentContextHolder.get(CURRENT_CONTEXT_KEY);
        LoggerUtils.error(CommonLogger.ERROR, e, "methodName=", methodName, "[", CommonResultCode.ILLEGAL_REQ_PARAMETER.getCode(), "]");

        // 接口失败监控
        Map<String,String> tags = Maps.newHashMap();
        tags.put("method", methodName);
        nicetuanLookoutRegistry.counterInc("NicetuanWeappControllerAspectOtherException", tags);

       /* Id registryId = registry.createId("NicetuanWeappControllerAspectOtherException").withTag("method", methodName);
        registry.counter(registryId).inc();*/

        CurrentContextHolder.remove(CURRENT_CONTEXT_KEY);
        return ResponseUtils.create(CommonResultCode.ILLEGAL_REQ_PARAMETER);
    }

    /**
     * 判断支持的类型
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    @Override
    public Object handleEmptyBody(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return body;
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
        Method method = methodParameter.getMethod();
        String methodName = StringUtils.join(method.getDeclaringClass().getName(), ".", method.getName());
        CurrentContextHolder.put(CURRENT_CONTEXT_KEY, methodName);
        return httpInputMessage;
    }

    @Override
    public Object afterBodyRead(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return body;
    }

}
